using HCore.IOC.Beans.Factory.Attribute.Attr;
using HCore.Tests.Runtime.ShootingEditor2D.Scripts.Command;
using HCore.Tests.Runtime.ShootingEditor2D.Scripts.Support;
using HCore.Tests.Runtime.ShootingEditor2D.Scripts.System.GunSystem;
using HCore.Unity.Core;
using HCore.Unity.Manager;
using UnityEngine;

namespace HCore.Tests.Runtime.ShootingEditor2D.Scripts.ViewController.GamePlay
{
    public class Player : HCoreCommandMonoBehaviour
    {
        /// <summary>
        ///     碰撞检测器，检测是否和地面碰撞在一起的
        /// </summary>
        private TriggerCheck2D mGroundTriggerCheck2D;

        /// <summary>
        ///     玩家手上的枪
        /// </summary>
        private Gun mGunComponent;

        [Autowired] private IGunSystem mGunSystem;

        [Autowired] private InputManager mInputManager;

        /// <summary>
        ///     玩家钢体
        /// </summary>
        private Rigidbody2D mPlayerRigidBody2D;

        protected override void Awake()
        {
            base.Awake();
            mPlayerRigidBody2D = GetComponent<Rigidbody2D>();
            mGroundTriggerCheck2D = Get("GroundCheck").GetComponent<TriggerCheck2D>();
            mGunComponent = Get("Gun").GetComponent<Gun>();

            mInputManager.AddAxisListener(TriggerPoint.FixedUpdate, InputType.Horizontal, PlayerMove);
            mInputManager.AddKeyboardListener(TriggerPoint.Update, InputType.KeyDown, KeyCode.K, PlayerJump);
            mInputManager.AddKeyboardListener(TriggerPoint.Update, InputType.KeyDown, KeyCode.J, Fire);
            mInputManager.AddKeyboardListener(TriggerPoint.Update, InputType.KeyDown, KeyCode.R, ReloadBullet);
            mInputManager.AddKeyboardListener(TriggerPoint.Update, InputType.KeyDown, KeyCode.Q, ShiftGun);
        }

        protected override void OnDestroy()
        {
            mInputManager.RemoveKeyboardListener(TriggerPoint.Update, InputType.KeyDown, KeyCode.Q, ShiftGun);
            mInputManager.RemoveKeyboardListener(TriggerPoint.Update, InputType.KeyDown, KeyCode.R, ReloadBullet);
            mInputManager.RemoveKeyboardListener(TriggerPoint.Update, InputType.KeyDown, KeyCode.J, Fire);
            mInputManager.RemoveKeyboardListener(TriggerPoint.Update, InputType.KeyDown, KeyCode.K, PlayerJump);
            mInputManager.RemoveAxisListener(TriggerPoint.FixedUpdate, InputType.Horizontal, PlayerMove);
            base.OnDestroy();
        }

        private void ShiftGun(KeyCode obj)
        {
            // 非闲置状态，不能切枪
            if (mGunSystem.CurrentGun.GunState.Value != GunState.Idle
                // 不能切枪
                || !mGunSystem.CanShiftGun) return;
            // 切枪
            SendCommand(new ShiftGunCommand());
        }

        /// <summary>
        ///     装载子弹
        /// </summary>
        /// <param name="obj"></param>
        private void ReloadBullet(KeyCode obj)
        {
            mGunComponent.Reload();
        }

        private void Fire(KeyCode obj)
        {
            mGunComponent.Shoot();
        }

        /// <summary>
        ///     跳跃
        /// </summary>
        /// <param name="obj"></param>
        private void PlayerJump(KeyCode obj)
        {
            if (mGroundTriggerCheck2D.Triggered) mPlayerRigidBody2D.linearVelocityY = 5f;
        }

        // 给钢体一个移动速率，*5 比较适合
        /// <summary>
        ///     左右移动
        /// </summary>
        /// <param name="horizontalMovement"></param>
        private void PlayerMove(float horizontalMovement)
        {
            var localScale = transform.localScale;
            var localScaleX = localScale.x;

            if (
                // 如果移动速率大于0（向右移动），且缩放小于0（面朝左边）
                (horizontalMovement > 0 && localScaleX < 0)
                // 如果移动速率小于0（向左移动），且缩放大于0（面朝右边）
                || (horizontalMovement < 0 && localScaleX > 0)
            )
            {
                localScale.x = -localScale.x;
                transform.localScale = localScale;
            }

            // 给钢体一个移动速率，*5 比较适合
            mPlayerRigidBody2D.linearVelocityX = horizontalMovement * 5;
        }

        /// <summary>
        ///     是否面朝右边
        ///     <para>1:朝右</para>
        ///     <para>-1:朝左</para>
        /// </summary>
        /// <returns></returns>
        public float IsRight()
        {
            return Mathf.Sign(transform.localScale.x); // 获取到缩放值的正负符号
        }
    }
}